package org.flowable.editor.language.json.converter;

import com.dragon.flow.util.ExtansionPropertiesUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.BaseElement;
import org.flowable.bpmn.model.CallActivity;
import org.flowable.bpmn.model.FlowElement;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 流程设计器 Activity 属性拓展
 */
public class FyCallActivityJsonConverter extends CallActivityJsonConverter {

    private static final String MODEL_BPMN_EXTENSION = "modelBpmnExtension";

    public static final List<String> extensionElements = Lists.newArrayList(
            MODEL_BPMN_EXTENSION
    );

    public static void customFillTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap, Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {
        fillJsonTypes(convertersToBpmnMap);
        fillBpmnTypes(convertersToJsonMap);
    }

    public static void fillJsonTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap) {
        convertersToBpmnMap.put(STENCIL_CALL_ACTIVITY, FyCallActivityJsonConverter.class);
    }

    public static void fillBpmnTypes(Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {
        convertersToJsonMap.put(CallActivity.class, FyCallActivityJsonConverter.class);
    }

    @Override
    protected void convertElementToJson(ObjectNode propertiesNode, BaseElement baseElement,
                                        BpmnJsonConverterContext converterContext) {
        super.convertElementToJson(propertiesNode, baseElement, converterContext);
        Map<String, String> extensionElementValues = new HashMap<>();

        baseElement.getExtensionElements().forEach((s, elements) -> elements.forEach(extensionElement -> {
            String elementName = extensionElement.getName();
            if (extensionElements.contains(elementName)) {
                extensionElementValues.put(elementName, extensionElement.getElementText());
            }
        }));
        extensionElementValues.forEach((key, value) -> {
            if (StringUtils.isNotBlank(value)) {
                propertiesNode.put(key, value);
            }
        });
    }

    @Override
    protected FlowElement convertJsonToElement(JsonNode elementNode, JsonNode modelNode, Map<String, JsonNode> shapeMap, BpmnJsonConverterContext converterContex) {
        FlowElement flowElement = super.convertJsonToElement(elementNode, modelNode, shapeMap, converterContex);
        this.addExtendPropertiesElement(flowElement, elementNode);
        return flowElement;
    }

    private void addExtendPropertiesElement(FlowElement flowElement, JsonNode elementNode) {
        if (flowElement instanceof CallActivity){
            CallActivity callActivity = (CallActivity) flowElement;
            extensionElements.forEach(name -> ExtansionPropertiesUtil.addExtansionPropertiesElement(elementNode, callActivity, name));
        }
    }

}
